package com.clothing.customization.service.impl;

import com.clothing.customization.dto.MaterialInventoryDTO;
import com.clothing.customization.dto.MaterialInventoryQueryDTO;
import com.clothing.customization.entity.MaterialInventory;
import com.clothing.customization.repository.MaterialInventoryRepository;
import com.clothing.customization.service.MaterialInventoryService;
import jakarta.persistence.criteria.Predicate;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 面料库存服务实现类
 */
@Service
@RequiredArgsConstructor
public class MaterialInventoryServiceImpl implements MaterialInventoryService {
    
    private final MaterialInventoryRepository materialInventoryRepository;
    
    @Override
    public Page<MaterialInventoryDTO> getList(MaterialInventoryQueryDTO queryDTO) {
        // 创建分页和排序条件
        PageRequest pageRequest = PageRequest.of(
            queryDTO.getPageNum() - 1,
            queryDTO.getPageSize(),
            Sort.by(Sort.Direction.DESC, "createTime")
        );
        
        // 创建查询条件
        Specification<MaterialInventory> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            // 面料编号
            if (StringUtils.hasText(queryDTO.getMaterialCode())) {
                predicates.add(cb.like(root.get("materialCode"), 
                    "%" + queryDTO.getMaterialCode() + "%"));
            }
            
            // 面料名称
            if (StringUtils.hasText(queryDTO.getMaterialName())) {
                predicates.add(cb.like(root.get("materialName"), 
                    "%" + queryDTO.getMaterialName() + "%"));
            }
            
            // 面料类型
            if (StringUtils.hasText(queryDTO.getMaterialType())) {
                predicates.add(cb.equal(root.get("materialType"), 
                    queryDTO.getMaterialType()));
            }
            
            // 颜色
            if (StringUtils.hasText(queryDTO.getColor())) {
                predicates.add(cb.equal(root.get("color"), 
                    queryDTO.getColor()));
            }
            
            // 供应商
            if (StringUtils.hasText(queryDTO.getSupplier())) {
                predicates.add(cb.like(root.get("supplier"), 
                    "%" + queryDTO.getSupplier() + "%"));
            }
            
            return cb.and(predicates.toArray(new Predicate[0]));
        };
        
        // 执行分页查询
        return materialInventoryRepository.findAll(specification, pageRequest)
            .map(this::convertToDTO);
    }
    
    @Override
    public MaterialInventoryDTO getDetail(Long id) {
        MaterialInventory inventory = materialInventoryRepository.findById(id)
            .orElseThrow(() -> new IllegalArgumentException("面料库存不存在"));
        return convertToDTO(inventory);
    }
    
    @Override
    @Transactional
    public MaterialInventoryDTO create(MaterialInventoryDTO dto) {
        // 验证面料编号是否已存在
        if (materialInventoryRepository.existsByMaterialCode(dto.getMaterialCode())) {
            throw new IllegalArgumentException("面料编号已存在");
        }
        
        MaterialInventory inventory = new MaterialInventory();
        BeanUtils.copyProperties(dto, inventory);
        
        return convertToDTO(materialInventoryRepository.save(inventory));
    }
    
    @Override
    @Transactional
    public MaterialInventoryDTO update(Long id, MaterialInventoryDTO dto) {
        MaterialInventory inventory = materialInventoryRepository.findById(id)
            .orElseThrow(() -> new IllegalArgumentException("面料库存不存在"));
        
        // 验证面料编号是否已被其他记录使用
        if (!inventory.getMaterialCode().equals(dto.getMaterialCode()) &&
                materialInventoryRepository.existsByMaterialCodeAndIdNot(
                    dto.getMaterialCode(), id)) {
            throw new IllegalArgumentException("面料编号已存在");
        }
        
        BeanUtils.copyProperties(dto, inventory);
        inventory.setId(id); // 确保ID不被覆盖
        
        return convertToDTO(materialInventoryRepository.save(inventory));
    }
    
    @Override
    @Transactional
    public void delete(Long id) {
        if (!materialInventoryRepository.existsById(id)) {
            throw new IllegalArgumentException("面料库存不存在");
        }
        materialInventoryRepository.deleteById(id);
    }
    
    /**
     * 将实体对象转换为DTO
     */
    private MaterialInventoryDTO convertToDTO(MaterialInventory inventory) {
        MaterialInventoryDTO dto = new MaterialInventoryDTO();
        BeanUtils.copyProperties(inventory, dto);
        return dto;
    }
} 